package com.ys.dubbo.cloud.dubbocloudredisv1gateway.config;


import com.ys.dubbo.cloud.dubbocloudredisv1gateway.model.GatewayRouteDefinition;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>@description:</p>
 *
 * @author yangshuang
 * @version 1.0
 * @date 2019/7/16 13:00
 */
@Slf4j
@Component(value = "redisRouteDefinitionWriter")
@AllArgsConstructor
public class RedisRouteDefinitionWriter implements RouteDefinitionRepository {
    private final RedisTemplate redisTemplate;

    private static final String ROUTE_KEY = "";

    @Override
    public Mono<Void> save(Mono<RouteDefinition> route) {
        return route.flatMap(r -> {
            GatewayRouteDefinition vo = new GatewayRouteDefinition();
            BeanUtils.copyProperties(r, vo);
            log.info("保存路由信息{}", vo);
            redisTemplate.opsForHash().put(ROUTE_KEY, r.getId(), vo);
            return Mono.empty();
        });
    }

    @Override
    public Mono<Void> delete(Mono<String> routeId) {
        routeId.subscribe(id -> {
            log.info("删除路由信息{}", id);
            redisTemplate.opsForHash().delete(ROUTE_KEY, id);
        });
        return Mono.empty();
    }

    /**
     * 动态路由入口
     *
     * @return
     */
    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(GatewayRouteDefinition.class));
        List<GatewayRouteDefinition> values = redisTemplate.opsForHash().values(ROUTE_KEY);
        List<RouteDefinition> definitionList = values.stream().map(item -> {
            RouteDefinition routeDefinition = new RouteDefinition();
            BeanUtils.copyProperties(item, routeDefinition);
            return routeDefinition;
        }).collect(Collectors.toList());

        log.debug("redis 中路由定义条数： {}， {}", definitionList.size(), definitionList);
        return Flux.fromIterable(definitionList);
    }
}
